package com.tanhua.manage.service;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tanhua.manage.domain.AnalysisByDay;
import com.tanhua.manage.mapper.AnalysisByDayMapper;
import com.tanhua.manage.mapper.LogMapper;
import com.tanhua.manage.utils.ComputeUtil;
import com.tanhua.manage.vo.AnalysisDataVo;
import com.tanhua.manage.vo.AnalysisSummaryVo;
import com.tanhua.manage.vo.AnalysisUsersVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class AnalysisService extends ServiceImpl<AnalysisByDayMapper, AnalysisByDay> {

    /**
     * 接口名称：概要统计信息
     */
    public ResponseEntity<Object> summary() {
        //1. 查询累计用户数
        //SELECT SUM(num_registered) num_registered FROM tb_analysis_by_day
        AnalysisByDay analysisByDay = query().select("SUM(num_registered) num_registered").one();
        Integer numRegistered = analysisByDay.getNumRegistered();

        //String now = "2021-03-08";
        //String yes = "2021-03-07";

        Date date = new Date();
        String now = new SimpleDateFormat("yyyy-MM-dd").format(date);
        String yes = ComputeUtil.offsetDay(date, -1);

        //2. 查询今日：新增用户、登陆次数、活跃用户
        // SELECT * FROM tb_analysis_by_day WHERE record_date='2021-03-08'
        AnalysisByDay todayAnalysis = query().eq("record_date", now).one();
        Integer todayRegister = todayAnalysis.getNumRegistered();
        Integer todayNumLogin = todayAnalysis.getNumLogin();
        Integer todayNumActive = todayAnalysis.getNumActive();

        //3. 查询昨日：新增用户、登陆次数、活跃用户
        AnalysisByDay yesAnalysis = query().eq("record_date", yes).one();
        Integer yesRegister = yesAnalysis.getNumRegistered();
        Integer yesNumLogin = yesAnalysis.getNumLogin();
        Integer yesNumActive = yesAnalysis.getNumActive();

        //4. 查询过去7天、30天活跃用户
        long day7 = this.baseMapper.findNumActiveByDate(ComputeUtil.offsetDay(date, -7), now);
        long day30 = this.baseMapper.findNumActiveByDate(ComputeUtil.offsetDay(date, -30), now);

        //5、创建返回的vo对象
        AnalysisSummaryVo vo = new AnalysisSummaryVo();
        // 累计用户数
        vo.setCumulativeUsers(numRegistered.longValue());
        // 设置今日：新增用户、登陆次数、活跃用户
        vo.setNewUsersToday(todayRegister.longValue());
        vo.setLoginTimesToday(todayNumLogin.longValue());
        vo.setActiveUsersToday(todayNumActive.longValue());
        // 设置涨跌率：新增用户、登陆次数、活跃用户
        vo.setNewUsersTodayRate(ComputeUtil.computeRate(todayRegister, yesRegister));
        vo.setLoginTimesTodayRate(ComputeUtil.computeRate(todayNumLogin, yesNumLogin));
        vo.setActiveUsersTodayRate(ComputeUtil.computeRate(todayNumActive, yesNumActive));

        // 设置过去7天、30天活跃用户
        vo.setActivePassMonth(day7);
        vo.setActivePassWeek(day30);

        return ResponseEntity.ok(vo);
    }

    @Autowired
    private LogMapper logMapper;
    @Autowired
    private AnalysisByDayMapper analysisByDayMapper;

    public void analysis() {
        //1. 获取当前时间
        Date date = new Date();
        String now = new SimpleDateFormat("yyyy-MM-dd").format(date);

        //2. 根据当前时间查询日表
        AnalysisByDay analysisByDay = query().eq("record_date", now).one();
        //3. 如果没有查询到今日统计数据，就执行插入
        if (analysisByDay == null) {
            analysisByDay = new AnalysisByDay();
            analysisByDay.setNumRetention1d(0);
            analysisByDay.setNumActive(0);
            analysisByDay.setNumLogin(0);
            analysisByDay.setNumRegistered(0);
            analysisByDay.setCreated(new Date());
            analysisByDay.setUpdated(new Date());
            analysisByDay.setRecordDate(date);
            // 保存
            analysisByDayMapper.insert(analysisByDay);
        }
        // 获取昨天的时间
        String yes = ComputeUtil.offsetDay(date, -1);

        //4. 更新日表
        //4.1 查询新注册用户数
        Long numRegister = logMapper.queryNumsByType("0102", now);
        //4.2 登陆次数
        Long numLogin = logMapper.queryNumsByType("0101", now);
        //4.3 活跃用户总数
        Long numActive = logMapper.queryNumsByDate(now);
        //4.4 次日留存 （昨天注册，今天登陆）
        Long numRetention1d = logMapper.queryNumRetention1d(now, yes);

        //4.5 设置查询的数据到日表对象中
        analysisByDay.setNumRegistered(numRegister.intValue());
        analysisByDay.setNumLogin(numLogin.intValue());
        analysisByDay.setNumActive(numActive.intValue());
        analysisByDay.setNumRetention1d(numRetention1d.intValue());
        analysisByDay.setUpdated(new Date());
        //4.6 更新日表
        analysisByDayMapper.updateById(analysisByDay);
    }

    /**
     * 接口名称：新增、活跃用户、次日留存率
     */
    public ResponseEntity<Object> queryAnalysisUsers(Long sd, Long ed, Integer type) {
        //得到开始时间对应的日期字符串
        String startDate = new SimpleDateFormat("yyyy-MM-dd").format(sd);
        //得到开始时间对应的日期字符串
        String endDate = new SimpleDateFormat("yyyy-MM-dd").format(ed);
        //今年数据
        List<AnalysisDataVo> thisYear = queryAnalysisDataVo(startDate, endDate, type);

        //得到开始时间对应去年的日期字符串
        Calendar instance = Calendar.getInstance();
        instance.setTime(new Date(sd));
        instance.add(Calendar.YEAR,-1);//日期减1年
        Date lastYearStartDate = instance.getTime();
        String lastYearStartDateStr = new SimpleDateFormat("yyyy-MM-dd").format(lastYearStartDate);
        //得到开始时间对应去年的日期字符串
        instance.setTime(new Date(ed));
        instance.add(Calendar.YEAR,-1);//日期减1年
        Date lastYearEndDate = instance.getTime();
        String lastYearEndDateStr = new SimpleDateFormat("yyyy-MM-dd").format(lastYearEndDate);
        //去年数据
        List<AnalysisDataVo> lastYear = queryAnalysisDataVo(lastYearStartDateStr, lastYearEndDateStr, type);

        //构造返回给前端的Vo
        AnalysisUsersVo analysisUsersVo = new AnalysisUsersVo(thisYear, lastYear);
        return ResponseEntity.ok(analysisUsersVo);
    }

    public List<AnalysisDataVo> queryAnalysisDataVo(String startDate, String endDate, Integer type) {
        //得到起始时间和结束时间之间的所有AnalysisByDay数据
        List<AnalysisByDay> analysisByDayList = query().ge("record_date", startDate).le("record_date", endDate).list();
        //构造要返回的每日数据点集合
        List<AnalysisDataVo> analysisDataVoList = new ArrayList<>();

        for (AnalysisByDay analysisByDay : analysisByDayList) {
            AnalysisDataVo analysisDataVo = new AnalysisDataVo();
            analysisDataVo.setTitle(new SimpleDateFormat("yyyy-MM-dd").format(analysisByDay.getRecordDate()));
            //根据查询类型，设置返回的数据点的数量
            switch (type) {//101 新增 102 活跃用户 103 次日留存率
                case 101:
                    analysisDataVo.setAmount(analysisByDay.getNumRegistered());
                    break;
                case 102:
                    analysisDataVo.setAmount(analysisByDay.getNumActive());
                    break;
                case 103:
                    analysisDataVo.setAmount(analysisByDay.getNumRetention1d());
                    break;
            }
            //把每日数据点添加到要返回的每日数据点集合
            analysisDataVoList.add(analysisDataVo);
        }

        return analysisDataVoList;
    }
}

